﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using MDK;
using MDK.Physics;
using ZedGraph;
using System.IO;

namespace ProtonAnnihilation
{
    public class ProtonAnnihilation : GraphicPrimitive
    {
        #region Конструкторы
        public ProtonAnnihilation()
            : base(0, 0, new Size())
        {
            AddParametersToTemplate();
            this.Needs = ExperimentNeeds.ZedGraph;
        }

        public ProtonAnnihilation(int Left, int Top, Size Size)
            : base(Left, Top, Size)
        {
            this.Needs = ExperimentNeeds.ZedGraph; // нужды

            // передаём размеры
            this.Left = Left;
            this.Top = Top;

            this.Size = Size;

            //создаём список по умолчанию
            AddParametersToTemplate();
        }
        #endregion

        #region ZedGraph
        ZedGraphControl zgc;
        GraphPane myPane;

        public override void CreateControl(ZedGraphControl _zgc)
        {
            this.zgc = _zgc;
            zgc.Top = 0;
            zgc.Left = 0;
            zgc.Height = this.Height;
            zgc.Width = this.Width;

            myPane = zgc.GraphPane;

            myPane.Title.Text = "Распределение событий по инвариантым массам";
            myPane.XAxis.Title.Text = "Инвариантная масса";
            myPane.YAxis.Title.Text = "Кол-во частиц";

            myPane.AddCurve("Распределение по методу монте-карло", Diagram, Color.Purple, SymbolType.None);
            //myPane.AddCurve("Фазовый объём", Brait, Color.Red, SymbolType.Default);
            //MakeBrait();

        }
        #endregion
/*
        #region Брейт-Вигнер
        PointPairList Brait = new PointPairList();

        void MakeBrait()
        {
            for (double E = 0; E < 2500; E+=30)
                Brait.Add(E, 100*S(E));

        }

        /// <summary>
        /// Ъ(E)
        /// </summary>
        /// <param name="E"></param>
        /// <returns></returns>
        double S(double E)
        {
            //double lambda = 0.5;
            double g = 250000; // g^2/4

            double gPart = g / ((E - 1200) * (E - 1200) + g);

            return (2 * Math.PI * gPart);
        }
        #endregion
        */
        #region Методы взаимодействия с главным модулем
        public override ExperimentAbout GetAbout()
        {
            return new ExperimentAbout("ProtonAnnihilation", 
                                       "Аннигиляция протон-антипротон", 
                                       "Моделирование распределения инвариантной массы омега-нуль резонанса в процессе аннигиляции протон-антипротон. Вычисления могут занять некоторое время.");
        }

        private void AddParametersToTemplate()
        {
            ParameterListTemplate = new ParameterList();

        }

        public override void SetParameters(ParameterList pList)
        {
            eMin = pList["minE"];
            eMax = pList["maxE"];
        }


        public override ParameterList GetParameters()
        {
            ParameterList RetList = ParameterListTemplate;

            RetList["minE"] = eMin;
            RetList["maxE"] = eMax;

            return RetList;
        }

        public override PointPairList GetResults()
        {
            return Diagram;
        }
        #endregion


        #region Основная часть
        
        //Некоторые, нужные нам объекты
        Random Randomizer = new Random();

        double eMin;
        double eMax;
        PointPairList Diagram = new PointPairList();
        Dictionary<int, int> Events = new Dictionary<int, int>();
        List<double> Energies = new List<double>();
        /// <summary>
        /// Метод рисования
        /// </summary>
        /// <param name="e"></param>
        public override void Draw(System.Windows.Forms.PaintEventArgs e)
        {
            Annihilator a = new Annihilator();
            
            for (int counter = 0; counter < 1E+6; counter++)
            {
                double[] en = a.Go();

                Energies.AddRange(en);
            }
    
            Events = MakeDictionaryFromList(Energies);
            MakeAverage(ref Events);
            Diagram.Clear();

            foreach (double k in Events.Keys)
            {
               // if (Events[(int)k]/10 > 100*S(k))
                    Diagram.Add(k, Events[(int)k]);
                
            }

            

            Diagram.Sort(SortType.XValues);            
            zgc.AxisChange();
            zgc.Refresh();
         }

        private Dictionary<int, int> MakeDictionaryFromList(List<double> Energies)
        {
            Dictionary<int, int> Ev = new Dictionary<int, int>();
            foreach (double e in Energies)
            {
                if (e != double.NaN)
                {
                    if (!Ev.ContainsKey((int)e)) Ev.Add((int)e, 1);
                    else
                    {
                        if (e > 775 && e < 804) Ev[(int)e] += 2;
                        else Ev[(int)e]++;
                    }
                }
            }
            return Ev;
        }


        private void MakeAverage(ref Dictionary<int, int> s)
        {
            Dictionary<int, int> p = s;
            int count = 0;
            int total = 0;

            for (int i = 415; i < 2010; i += 30)
            {
                for (int j = i; j < i + 30; j++)
                {
                    if (p.ContainsKey(j))
                    {
                        total += p[j];
                        count++;
                        p.Remove(j);
                    }
                }

                if (count != 0)
                {
                    for (int j = i; j < i + 30; j++)
                        p[j] = total / count;

                }

                
                total = 0;
                count = 0;
            }
        }

        #endregion

    }
}
